import {ref, computed, reactive, watchEffect} from 'vue'
import {defineStore} from 'pinia'

import {utils} from "yklib";
const {
    cal_pillar_diameter,
    calRopeDiameter,
    calRopeMassPer100m, calShaftDiameter,
    getRopeClass,
    getRopeCoreClass,
    getRopeStrands
} = utils;

export const useSgesAStore = defineStore('sgesCalA', () => {

    const capChargeTotalSta = ref<number>(209.3945)
    const powerChargeTotalSta = ref<number>(52.3845)
    const totalChargeTime = ref<number>(4)
    const cal_power = ref<boolean>(true)
    const vibrant_para = ref<number>(1);

    const vibrant_option = [
        {
            label: "有效提升高度",
            value: 1,
        }, {
            label: "重物块密度",
            value: 2
        }, {
            label: "重物块长",
            value: 3
        }, {
            label: "重物块宽",
            value: 4
        }, {
            label: "重物块高",
            value: 5
        }, {
            label: "系统效率",
            value: 6
        }
    ]

    watchEffect(() => {
        if (cal_power.value) {
            powerChargeTotalSta.value = computed(() => capChargeTotalSta.value / totalChargeTime.value).value
        } else {
            totalChargeTime.value = computed(() => capChargeTotalSta.value / powerChargeTotalSta.value).value
        }
    })

    const heightTower = ref(150)  // 1
    const density = ref(2400)  // 2
    const lengthBlock = ref(6) // 3
    const widthBlock = ref(3); // 4
    const heightBlock = ref(19); // 5
    const etaSystem = ref(0.85)
    const volumeBlock = ref(0)
    const massBlock = ref(0)
    const etaCharge = ref(1)
    const etaDischarge = ref(1)

    const numOfTowers = ref(9);
    const numOfGroups = ref(16);
    const numBlocksPerGroup = ref(4)
    const totalBlocksNum = computed(() => numOfTowers.value * numOfGroups.value * numBlocksPerGroup.value)
    const totalMassBlocks = ref(0)
    const totalGravityEnergy = ref(0)
    const g = ref(9.8)
    const rowWeightPerTower = computed(() => numOfGroups.value / 2)
    const colWeightPerTower = computed(() => 2 * numBlocksPerGroup.value)
    const numBlocksPerTower = computed(() => colWeightPerTower.value * rowWeightPerTower.value)
    watchEffect(() => {
        switch (vibrant_para.value) {
            case 1:
                volumeBlock.value = computed(() => heightBlock.value * widthBlock.value * lengthBlock.value).value
                massBlock.value = computed(() => volumeBlock.value * density.value).value  // kg
                totalMassBlocks.value = computed(() => massBlock.value * totalBlocksNum.value).value  // kg
                etaDischarge.value = computed(() => Math.sqrt(etaSystem.value)).value
                etaCharge.value = computed(() => Math.sqrt(etaSystem.value)).value
                totalGravityEnergy.value = computed(() => capChargeTotalSta.value * 3600000000 * etaCharge.value).value  // J
                heightTower.value = computed(() => totalGravityEnergy.value / totalMassBlocks.value / g.value).value
                break
            case 2:
                volumeBlock.value = computed(() => heightBlock.value * widthBlock.value * lengthBlock.value).value
                etaDischarge.value = computed(() => Math.sqrt(etaSystem.value)).value
                etaCharge.value = computed(() => Math.sqrt(etaSystem.value)).value
                totalGravityEnergy.value = computed(() => capChargeTotalSta.value * 3600000000 * etaCharge.value).value
                totalMassBlocks.value = computed(() => totalGravityEnergy.value / heightTower.value / g.value).value
                massBlock.value = computed(() => totalMassBlocks.value / totalBlocksNum.value).value
                density.value = computed(() => massBlock.value / volumeBlock.value).value
                break
            case 3:
                etaDischarge.value = computed(() => Math.sqrt(etaSystem.value)).value
                etaCharge.value = computed(() => Math.sqrt(etaSystem.value)).value
                totalGravityEnergy.value = computed(() => capChargeTotalSta.value * 3600000000 * etaCharge.value).value
                totalMassBlocks.value = computed(() => totalGravityEnergy.value / heightTower.value / g.value).value
                massBlock.value = computed(() => totalMassBlocks.value / totalBlocksNum.value).value
                volumeBlock.value = computed(() => massBlock.value / density.value).value
                lengthBlock.value = computed(() => volumeBlock.value / widthBlock.value / heightBlock.value).value
                break
            case 4:
                etaDischarge.value = computed(() => Math.sqrt(etaSystem.value)).value
                etaCharge.value = computed(() => Math.sqrt(etaSystem.value)).value
                totalGravityEnergy.value = computed(() => capChargeTotalSta.value * 3600000000 * etaCharge.value).value
                totalMassBlocks.value = computed(() => totalGravityEnergy.value / heightTower.value / g.value).value
                massBlock.value = computed(() => totalMassBlocks.value / totalBlocksNum.value).value
                volumeBlock.value = computed(() => massBlock.value / density.value).value
                widthBlock.value = computed(() => volumeBlock.value / lengthBlock.value / heightBlock.value).value
                break
            case 5:
                etaDischarge.value = computed(() => Math.sqrt(etaSystem.value)).value
                etaCharge.value = computed(() => Math.sqrt(etaSystem.value)).value
                totalGravityEnergy.value = computed(() => capChargeTotalSta.value * 3600000000 * etaCharge.value).value
                totalMassBlocks.value = computed(() => totalGravityEnergy.value / heightTower.value / g.value).value
                massBlock.value = computed(() => totalMassBlocks.value / totalBlocksNum.value).value
                volumeBlock.value = computed(() => massBlock.value / density.value).value
                heightBlock.value = computed(() => volumeBlock.value / lengthBlock.value / widthBlock.value).value
                break
            case 6: // eta
                volumeBlock.value = computed(() => heightBlock.value * widthBlock.value * lengthBlock.value).value
                massBlock.value = computed(() => volumeBlock.value * density.value).value
                totalMassBlocks.value = computed(() => massBlock.value * totalBlocksNum.value).value
                totalGravityEnergy.value = computed(() => totalMassBlocks.value * g.value * heightTower.value).value
                etaCharge.value = computed(() => totalGravityEnergy.value / capChargeTotalSta.value / 3600000000).value
                etaDischarge.value = computed(() => etaCharge.value).value
                etaSystem.value = computed(() => etaCharge.value * etaDischarge.value).value
                break
            default:
                volumeBlock.value = computed(() => heightBlock.value * widthBlock.value * lengthBlock.value).value
                massBlock.value = computed(() => volumeBlock.value * density.value).value
                break

        }


    })
    const totalGravityEnergy_MJ = computed(() => totalGravityEnergy.value / 1000000)
    const capDischargeTotalSta = computed(() => capChargeTotalSta.value * etaSystem.value)
    const weightBlock = computed(() => massBlock.value * g.value)
    const etaCharge_100 = computed(() => etaCharge.value * 100)
    const etaDischarge_100 = computed(() => etaDischarge.value * 100)
    const etaSystem_100 = computed(() => etaSystem.value * 100)

    const totalMassAssistance_t = ref(50000);
    const totalMassAssistance = computed(() => totalMassAssistance_t.value * 1000);
    const totalWeightAssistance = computed(() => totalMassAssistance.value * g.value)

    const pillar_set = reactive({
        steelType: "Q235",
        steelDensity: 7.85,
        concreteType: "C70",
        concreteDensity: 2.5,
        steelRatio: 0.14,
        safetyFactor: 1.5,
    })

    const diameter_pillar = computed(() => {
        return cal_pillar_diameter(pillar_set, heightTower, weightBlock, g) / 1000
    })  // 承重柱直径,mm

    const distancePillarWeight = ref(0.2)
    const widthGenRegion = ref(4) // 发电机列的宽度，不包含柱子的尺寸
    const areaControlRoom = ref(50)  // 集控室占地面积

    const widthSingleTower = computed(() => {
        let _1 = rowWeightPerTower.value * (widthBlock.value + 2 * distancePillarWeight.value) // 重物和间隙的总宽度
        let _2 = (rowWeightPerTower.value + 1) * diameter_pillar.value // 宽度方向柱子的总尺寸
        return _1 + _2
    })

    const lengthSingleTower = computed(() => {
        let _1 = colWeightPerTower.value * (lengthBlock.value + 2 * distancePillarWeight.value)
        let _2 = (colWeightPerTower.value + 2) * diameter_pillar.value// 长度方向柱子的总尺寸
        return _1 + _2 + widthGenRegion.value
    })

    const areaSingleTower = computed(() => widthSingleTower.value * lengthSingleTower.value)
    const areaTotalTower = computed(() => areaSingleTower.value * numOfTowers.value)
    const areaTotalSta = computed(() => areaTotalTower.value + areaControlRoom.value)
    const areaCoe = ref(1)

    // 同时运行的重物占比，如果同时运行1/4，且充电时间为4小时，则单程运行需要1小时，如果同时运行1/2，且充电时间为4小时，则单程运行需要2小时
    const timeSinglePass = ref(1)
    const proSim = computed(() => timeSinglePass.value / totalChargeTime.value)
    // const proSim = ref(0.25)
    // const timeSinglePass = computed(() => totalChargeTime.value * proSim.value)
    const numGroupsSim = computed(() => proSim.value * rowWeightPerTower.value)

    const velWeight_m_h = computed(() => heightTower.value / timeSinglePass.value)
    const velWeight_m_s = computed(() => velWeight_m_h.value / 3600)
    const powerSingleBlock = computed(() => velWeight_m_s.value * weightBlock.value) // 单个重物的运行功率
    const powerSingleBlock_MW = computed(() => powerSingleBlock.value / 1000000)
    const speedRotateGen = ref(600)

    // 额定工况下同时运行的重物的功率
    const powerBlocksSim = computed(() => powerSingleBlock.value * numBlocksPerTower.value * proSim.value)
    // 单个发电机的功率
    const chargePowerSingleGen = computed(() => powerBlocksSim.value / etaCharge.value)
    const disChaPowerSingleGen = computed(() => powerBlocksSim.value * etaDischarge.value)
    const chargePowerSingleGen_MW = computed(() => chargePowerSingleGen.value / 1000000)
    const disChaPowerSingleGen_MW = computed(() => disChaPowerSingleGen.value / 1000000)
    const chargePower = computed(() => chargePowerSingleGen.value * numOfTowers.value)
    const disChaPower = computed(() => disChaPowerSingleGen.value * numOfTowers.value)

    // torque = 9550P/N，因为是双出轴发电电动机，所以功率需要除以2
    const torqueMainShaft = computed(() => chargePowerSingleGen.value * 9.549 / speedRotateGen.value / 2)
    const speedRatio1 = ref(1.2) // 螺伞齿轮箱变速比
    const speedHMinorShaft = computed(() => speedRotateGen.value / speedRatio1.value)
    // 副轴高速段功率，不考虑变速箱效率
    const powerMinorShaft = computed(() => numBlocksPerGroup.value * powerSingleBlock.value)
    const torqueHMinorShaft = computed(() => powerMinorShaft.value * 9.549 / speedHMinorShaft.value)

    const numRopePerBlock = ref(4)
    const numPulleyPerRope = ref(8);
    const safetyRatioRope = ref(5)  // 钢丝绳安全系数，取值5~9

    const forceRope = computed(() => weightBlock.value / numRopePerBlock.value / (2 * numPulleyPerRope.value + 1))
    const forceRopeBreak = computed(() => forceRope.value * safetyRatioRope.value)
    const lvlRope = ref(1960);
    const ropeCoreClass = ref("天然纤维芯")
    const ropeCoreClasses = getRopeCoreClass()
    const ropeClass = ref("单层钢丝绳")
    const ropeClasses = getRopeClass()
    const ropeStrands = computed(() => getRopeStrands(ropeClass.value, ropeCoreClass.value))
    const ropeStrand = ref("6*7")
    const diameterRope_mm = computed(() => {
        return calRopeDiameter(forceRopeBreak.value, lvlRope.value, ropeClass.value, ropeCoreClass.value, ropeStrand.value)
    })
    const massRopePer100 = computed(() => {
        return calRopeMassPer100m(forceRopeBreak.value, lvlRope.value, ropeClass.value, ropeCoreClass.value, ropeStrand.value)
    })

    const dMainShaft_mm = computed(() => calShaftDiameter(chargePowerSingleGen.value / 2000, speedRotateGen.value))
    const dMinorShaftH_mm = computed(() => calShaftDiameter(powerMinorShaft.value / 1000, speedHMinorShaft.value))

    const ropeTripTimes = computed(() => 2 * numPulleyPerRope.value + 1)
    const lengthRopeGuidance = ref(160)
    const lengthRopeTrips = computed(() => ropeTripTimes.value * heightTower.value)
    const lengthRope = computed(() => lengthRopeGuidance.value + lengthRopeTrips.value)
    const velRope = computed(() => velWeight_m_s.value * ropeTripTimes.value)
    const diameterReel = ref(2.5)  // 卷筒直径
    const lengthReel = ref(1) // 卷筒卷线段长度
    const girthReel = computed(() => Math.PI * diameterReel.value) // 卷筒周长
    const speedLMinorShaft = computed(() => velRope.value * 60 / girthReel.value)  // 卷筒和副轴转速
    const dMinorShaft_mm = computed(() => calShaftDiameter(powerMinorShaft.value / 1000, speedLMinorShaft.value))
    const speedRatio2 = computed(() => speedHMinorShaft.value / speedLMinorShaft.value)

    const massSingleRope = computed(() => lengthRope.value / 100 * massRopePer100.value) // kg
    const massRopes = computed(() => massSingleRope.value * numRopePerBlock.value * totalBlocksNum.value)
    const numRopeLaps = computed(() => lengthRope.value / girthReel.value)
    const numLapsPerLayer = computed(() => lengthReel.value / diameterRope_mm.value * 1000)
    const numRopeLayers = computed(() => numRopeLaps.value / numLapsPerLayer.value)

    const lengthMainShaft = computed(() => widthBlock.value)
    const numMainShaft = computed(() => numOfTowers.value * rowWeightPerTower.value)
    const massMainShaft = computed(() => lengthMainShaft.value * Math.PI * (dMainShaft_mm.value / 2000) ** 2 * 7800)
    const massMainShafts = computed(() => massMainShaft.value * numMainShaft.value)
    const lengthMinorShaftH = computed(() => widthGenRegion.value / 4)
    const numMinorShaftH = computed(() => numOfTowers.value * numOfGroups.value)
    const massMinorShaftH = computed(() => lengthMinorShaftH.value * Math.PI * (dMinorShaftH_mm.value / 2000) ** 2 * 7800)
    const massMinorShaftHs = computed(() => numMinorShaftH.value * massMinorShaftH.value)

    const lengthMinorShaftL = computed(() => lengthBlock.value) // 副轴低速段长度
    const numMinorShaftL = computed(() => totalBlocksNum.value) // 副轴低速段数量
    const massMinorShaftL = computed(() => lengthMinorShaftL.value * Math.PI * (dMinorShaft_mm.value / 2000) ** 2 * 7800)
    // 副轴低速段总质量，L表示低速
    const massMinorShaftLs = computed(() => massMinorShaftL.value * numMinorShaftL.value)

    const lengthMinorShaftL0 = computed(() => widthGenRegion.value / 2 - lengthMinorShaftH.value)
    const massMinorShaftL0 = computed(() => lengthMinorShaftL0.value * Math.PI * (dMinorShaft_mm.value / 2000) ** 2 * 7800)
    const numMinorShaftL0 = computed(() => numOfTowers.value * numOfGroups.value)
    const massMinorShaftL0s = computed(() => numMinorShaftL0.value * massMinorShaftL0.value)
    // 所有主副轴的总质量
    const massShaftTotal = computed(() => massMainShafts.value + massMinorShaftHs.value + massMinorShaftL0s.value + massMinorShaftLs.value)

    const massTotalShaftAndRopes = computed(() => massShaftTotal.value + massRopes.value)
    const priceRope = ref(9000)
    const priceShaft = ref(20000)
    const priceRopes = computed(() => priceRope.value * massRopes.value / 1000)
    const priceShafts = computed(() => priceShaft.value * massShaftTotal.value / 1000)

    const calInfo = computed(() => {
        if (!Number.isInteger(numGroupsSim.value)) {
            return {
                success: false,
                msg: `<储能时长>、<单程运行时间>和<塔群中塔列数>设置相互矛盾，导致同时运行的塔列数为${numGroupsSim.value}，该数值不是整数，实际无法实现`
            }
        } else if (numRopePerBlock.value * lengthReel.value > lengthBlock.value + 2 * distancePillarWeight.value) {
            return {
                success: false,
                msg: `单个重物卷筒所需轴向总长度为${numRopePerBlock.value * lengthReel.value}，大于塔顶单个重物的长度方向总空间${lengthBlock.value + 2 * distancePillarWeight.value}，卷筒布置不下！`
            }
        } else if (diameterReel.value > widthBlock.value + 2 * distancePillarWeight.value) {
            return {
                success: false,
                msg: `卷筒直径为${diameterReel.value}，大于塔顶单个重物宽度方向总空间${widthBlock.value + 2 * distancePillarWeight.value}，卷筒布置不下！`
            }
        } else {
            return {
                success: true,
                msg: "success"
            }
        }
    })
    return {
        calInfo,
        numGroupsSim,
        priceRope,
        priceShaft,
        priceRopes,
        priceShafts,
        massShaftTotal,
        massTotalShaftAndRopes,
        massMinorShaftL0s,
        numMinorShaftL0,
        lengthMinorShaftL0,
        massMinorShaftL0,
        numRopeLaps,
        numLapsPerLayer,
        numRopeLayers,
        lengthMinorShaftL,
        numMinorShaftL,
        massMinorShaftL,
        massMinorShaftLs,
        lengthMinorShaftH,
        numMinorShaftH,
        massMinorShaftH,
        massMinorShaftHs,
        lengthMainShaft,
        numMainShaft,
        massMainShaft,
        massMainShafts,
        massRopes,
        massRopePer100,
        massSingleRope,
        speedRatio1,
        speedRatio2,
        ropeTripTimes,
        lengthRopeGuidance,
        lengthRopeTrips,
        lengthRope,
        velRope,
        diameterReel,
        lengthReel,
        girthReel,
        speedLMinorShaft,
        dMinorShaft_mm,
        dMainShaft_mm,
        dMinorShaftH_mm,
        ropeCoreClass,
        ropeCoreClasses,
        ropeClass,
        ropeClasses,
        ropeStrands,
        ropeStrand,
        lvlRope,
        forceRopeBreak,
        safetyRatioRope,
        diameterRope_mm,
        forceRope,
        numRopePerBlock,
        numPulleyPerRope,
        speedHMinorShaft,
        powerMinorShaft,
        torqueHMinorShaft,
        powerBlocksSim,
        torqueMainShaft,
        chargePower,
        disChaPower,
        chargePowerSingleGen_MW,
        disChaPowerSingleGen_MW,
        chargePowerSingleGen,
        disChaPowerSingleGen,
        powerSingleBlock,
        powerSingleBlock_MW,
        speedRotateGen,
        velWeight_m_h,
        velWeight_m_s,
        proSim,
        timeSinglePass,
        areaCoe,
        areaTotalSta,
        areaTotalTower,
        widthSingleTower,
        lengthSingleTower,
        areaSingleTower,
        areaControlRoom,
        distancePillarWeight,
        totalMassAssistance_t,
        totalMassAssistance,
        totalWeightAssistance,
        pillar_set,
        diameter_pillar,
        etaCharge_100,
        etaDischarge_100,
        etaSystem_100,
        capChargeTotalSta,
        capDischargeTotalSta,
        powerChargeTotalSta,
        totalChargeTime,
        cal_power,
        vibrant_para,
        vibrant_option,
        heightTower,
        density,
        lengthBlock,
        widthBlock,
        heightBlock,
        etaSystem,
        volumeBlock,
        massBlock,
        etaCharge,
        etaDischarge,
        numOfTowers,
        numOfGroups,
        numBlocksPerGroup,
        totalBlocksNum,
        totalMassBlocks,
        totalGravityEnergy,
        g,
        totalGravityEnergy_MJ,
        weightBlock,
        rowWeightPerTower,
        colWeightPerTower,
        numBlocksPerTower,
        widthGenRegion,
    }
})

